Amazon ElastiCache for Memcached に telnet で接続に成功してもすぐに「Connection closed by foreign host.」で切断される原因と対処方法
昨今では使う機会がめっきり減ったtelnet
コマンドですが ElastiCache for Memcached クラスターの接続テストにtelnet
コマンドを使います。 Memcached クラスターへtelnet で接続はできはするも、すぐに接続が切れるときの原因と対処方法を紹介します。
$ telnet wordpressmemchaed.yeuicp.cfg.apne1.cache.amazonaws.com 11211 # telnet でクラスターへ接続 Trying 10.0.34.175... Connected to wordpressmemchaed.yeuicp.cfg.apne1.cache.amazonaws.com. # 接続できた Escape character is '^]'. # エンターを数回入力すると... Connection closed by foreign host. # 接続が切断されてしまう
原因と対処早見
原因
telnet
で接続後、すぐに切断されるのは ElastiCache for Memcached クラスターの設定で転送中の暗号化が有効になっていることが原因です。
対処方法
暗号化非対応時
telnet
コマンドでの接続確認が必要な場合や、Memcached へ接続するアプリケーションが暗号通信に対応していない場合は、転送中の暗号化を無効にしてクラスターを作成する必要があります。転送中の暗号化設定はデプロイ後に変更できません。
転送中の暗号化を無効化した Memcached クラスターにはtelnet
コマンド接続後、すぐに切断されないためstats
コマンドなどを実行すると結果が返ってきます。
$ telnet mem2.yeuicp.0001.apne1.cache.amazonaws.com 11211 # 転送中の暗号化が無効のクラスターへ接続 Trying 10.0.33.7... Connected to mem2.yeuicp.0001.apne1.cache.amazonaws.com. # 接続できた Escape character is '^]'. stats # コマンド実行して結果が返ってくるし、切断もされない STAT pid 1 STAT uptime 469 STAT time 1692776705 STAT version 1.6.17 STAT libevent 2.1.11-stable --- 省略 ---
暗号化対応時
転送中の暗号化が有効だとtelnet
コマンドは使えません。代わりにopnessl
コマンドで接続テストができます。
$ openssl s_client -quiet -crlf -connect wordpressmemchaed.yeuicp.cfg.apne1.cache.amazonaws.com:11211 depth=2 C = US, O = Amazon, CN = Amazon Root CA 1 verify return:1 depth=1 C = US, O = Amazon, CN = Amazon RSA 2048 M01 verify return:1 depth=0 CN = *.wordpressmemchaed.yeuicp.apne1.cache.amazonaws.com verify return:1
接続テストでopenssl
コマンドで接続するのは問題なくても、実際に Memcached へアクセスするアプリケーションが暗号化通信に対応しているのかは重要な確認事項です。
telnet 接続が失敗した状況
WordPress のキャッシュプラグイン W3 Total Cache の設定をしていました。
データベースのキャッシュ先として Memcached が必要になり、ElastiCache for Memcached を構築しました。WordPress を導入した EC2 から Memcached クラスターへ接続できるかテストしようと以下のドキュメントを参考にtelnet
コマンドで試しました。
telnet
でクラスターへ接続はできはするも、なにか操作すると切断されてしまいます。
$ telnet wordpressmemchaed.yeuicp.cfg.apne1.cache.amazonaws.com 11211 Trying 10.0.34.175... Connected to wordpressmemchaed.yeuicp.cfg.apne1.cache.amazonaws.com. Escape character is '^]'. Connection closed by foreign host.
$ telnet wordpressmemchaed.yeuicp.cfg.apne1.cache.amazonaws.com 11211 Trying 10.0.34.175... Connected to wordpressmemchaed.yeuicp.cfg.apne1.cache.amazonaws.com. Escape character is '^]'. stats Connection closed by foreign host.
切り分け
転送中の暗号化が有効だとtelnet
ができないことがわかりました。
転送時の暗号化による MemCached クラスターへの接続 転送時の暗号化は、Memcached バージョン 1.6.12 以降を実行するクラスターでサポートされています。Telnet では、暗号化を使用しません。暗号化が有効な MemCached クラスターに接続するには、openssl クライアントを使用します。 ElastiCache Redit クラスターまたは ElastiCache Memcached クラスターへの接続をテストする | AWS re:Post
クラスターの設定を確認してみると転送中の暗号化が有効になっていました。
今回の症状はtelnet
で接続まではできるが、すぐに切断されるため「実質」接続できないという表現が適切です。接続ができるがゆえに切り分けに手こずりました。
転送中の暗号化が有効だとtelnet
コマンドは使えません。代わりにopnessl
コマンドで接続テストができます。正常に接続できコマンドも実行できました。
$ openssl s_client -quiet -crlf -connect wordpressmemchaed.yeuicp.cfg.apne1.cache.amazonaws.com:11211 depth=2 C = US, O = Amazon, CN = Amazon Root CA 1 verify return:1 depth=1 C = US, O = Amazon, CN = Amazon RSA 2048 M01 verify return:1 depth=0 CN = *.wordpressmemchaed.yeuicp.apne1.cache.amazonaws.com verify return:1
まとめ
EC2 から Memcached クラスターへの接続テストでは転送中の暗号化が有効していたため、telnet
は利用できずopenssl
で接続確認できることがわかりました。
W3 Total Chache プラグインからの接続はどうなのか?
telnet
やopenssl
からの接続はあくまでも接続テストであって、Memcached へ接続したいのは W3 Total Cache プラグインからのアクセスです。
私が調べた範囲では W3 Total Cache プラグインが暗号化通信に対応させるオプションはありませんでした。そのため転送中の暗号化を有効にした ElastiCache for Memcached クラスターへプラグインからの接続はできませんでした。
転送中の暗号化を無効にしたいところなのですが、クラスター作成後に転送中の暗号化の有効・無効の再設定はできません。転送中の暗号化を無効にしてクラスターを再作成しました。
転送中の暗号化を無効にしたクラスーたにはtelnet
での接続テストも問題なく成功し、W3 Total Cache からの接続テストも成功しました。
転送中の暗号化はいつ使うのか?
2022 年 5 月のアップデートで、ElastiCache for Memcached が転送中の暗号化をサポートしました。比較的新しくサポートされた機能です。
ドキュメントにベストプラクティスの記載があります。無条件に有効化することは正解ではないと読み取れます。
転送時の暗号化のベストプラクティス エンドポイントでデータの暗号化と復号を行うにはある程度の処理が必要であるため、転送時の暗号化の実装によりパフォーマンスが低下する可能性があります。自身のデータで転送時の暗号化使用時のベンチマークを暗号化なしの場合と比較して、実装におけるパフォーマンスの影響を判断してください。 新しい接続の作成には高い負荷がかかる場合があるため、TLS 接続を持続させることで転送時の暗号化のパフォーマンスへの影響を軽減させることができます。 ElastiCache の転送時の暗号化 (TLS) - Amazon ElastiCache
それもそのはずで Memcached で普及していた時代のアプリケーション、今回の様なプラグインが暗号化通信に対応しているか確認する必要があります。
ElastiCache for Memcached を採用するときは転送中の暗号化を有効にしても影響がないのかご確認ください。
まとめ
- ElastiCache for Memcached の転送中の暗号化設定はあとから変更できない
- 転送中の暗号化が有効化の場合、
telnet
での接続テストはできなくopenssl
で接続テストを行う - 接続テストが問題なかったとしても、アプリケーション、プラグインなどから暗号化通信して接続できるかは別問題
- アプリケーション、プラグインが暗号化通信に非対応の場合は ElastiCache for Memcached の転送中の暗号化は無効にする必要がある
おわりに
急ぎで Memcached が必要になり、ElastiCache for Memcached をデプロイしたのですが、EC2 からの接続テストにうまくいかず 40 分ほど時間を溶かした日がありました。同僚からの助言で「暗号化どうなってるの?」の一言で telnet 使うのに暗号化していたらダメかもしれんとなり、設定を見直したという一幕がありました。転送中の暗号化なしで ElastiCache for Memcached を再デプロイして解決に至りました。ElastiCache for Memcached のお作法、Memcached の理解の低さから招いた結果でしたので、本件のエラーと状況からトラブルシュートするときに本記事がどなたかのお役にたてれば幸いです。